package mvc.core.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;

/**
 * 共公工具类
 * 
 * @author liuzy
 * @version 2015年5月14日
 */
public class Util {

	/**
	 * 判断一个类是否实现了一个接口
	 * 
	 * @param clazz
	 * @param impl
	 * @return
	 */
	public static boolean isImpl(Class<?> clazz, Class<?> impl) {
		Class<?>[] impls = clazz.getInterfaces();
		if (impls != null && impls.length > 0) {
			for (Class<?> im : impls) {
				if (im.getName().equals(impl.getName()))
					return true;
			}
		}
		return false;
	}

	/**
	 * 把查询sql剪截为查询总数sql
	 * 
	 * @param sql
	 * @return
	 */
	public static String reSql(String sql) {
		sql = reBlank(sql);
		String sq = sql.substring(sql.indexOf("from") + 5, sql.length());
		int i = sq.lastIndexOf("limit");
		if (i != -1 && sq.substring(i, sq.length()).indexOf(")") == -1) {
			sq = sq.replace(sq.substring(i, sq.length()), "");
		}
		i = sq.lastIndexOf("order by");
		if (i != -1 && sq.substring(i, sq.length()).indexOf(")") == -1) {
			sq = sq.replace(sq.substring(i, sq.length()), "");
		}
		return "select count(*) from " + sq;
	}

	/**
	 * 替换多个连续空格为一个
	 * 
	 * @param sql
	 * @return
	 */
	private static String reBlank(String sql) {
		if (sql.indexOf("  ") == -1) {
			return sql;
		} else {
			return reBlank(sql.replaceAll("  ", " "));
		}
	}

	/**
	 * 把多个斜杠替换换为一个斜杠,例如/myAction//toDo
	 * 
	 * @param path
	 * @return
	 */
	public static String reSlash(String path) {
		if (path.indexOf("//") == -1) {
			return path;
		} else {
			return reSlash(path.replaceAll("//", "/"));
		}
	}

	/**
	 * 是空
	 */
	public static boolean isEmpty(String str) {
		return str == null || "".equals(str.trim());
	}

	/**
	 * 不是空
	 */
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	/**
	 * 获取WebRoot路径
	 * 
	 * @return
	 */
	public static String getWebRootPath() {
		String classPath = Util.class.getClassLoader().getResource("/").getPath();
		String rootPath = "";
		// windows下
		if ("\\".equals(File.separator)) {
			rootPath = classPath.substring(1, classPath.indexOf("/WEB-INF")).replace("/", "\\") + "\\";
		}
		// linux下
		if ("/".equals(File.separator)) {
			rootPath = classPath.substring(1, classPath.indexOf("/WEB-INF")).replace("\\", "/") + "/";
		}
		return rootPath;
	}

	/**
	 * 读取WebRoot目录下的文件
	 * 
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	@SuppressWarnings("resource")
	public static byte[] getFileBytes(String fileName) throws IOException {
		File file = new File(Util.getWebRootPath() + fileName);
		InputStream is = new FileInputStream(file);
		// 获取文件大小
		long length = file.length();
		if (length > Integer.MAX_VALUE) {
			throw new IOException(file.getName() + "文件太大");
		}
		// 创建一个数据来保存文件数据
		byte[] bytes = new byte[(int) length];
		// 读取数据到byte数组中
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
			offset += numRead;
		}
		// 确保所有数据均被读取
		if (offset < bytes.length) {
			throw new IOException(file.getName() + "没有完全读取");
		}
		is.close();
		return bytes;
	}

	/**
	 * 请求的参数的JSON形式
	 * 
	 * @param request
	 * @return
	 */
	public static String getJSON(HttpServletRequest request) {
		return JSON.toJSONString(getParamsMap(request));
	}

	/**
	 * 请求的attribute参数的Map形式
	 * 
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getAttributesMap(HttpServletRequest request) {
		Map<String, Object> paramsMap = new HashMap<>();
		if (request == null)
			return paramsMap;
		Enumeration<String> names = request.getAttributeNames();
		while (names.hasMoreElements()) {
			String name = (String) names.nextElement();
			paramsMap.put(name, request.getAttribute(name));
		}
		return paramsMap;
	}

	/**
	 * 请求的Attribute参数和Params参数的Map形式
	 * 
	 * @param request
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getParamsMap(HttpServletRequest request) {
		Map<String, Object> paramsMap = new HashMap<>();
		if (request == null)
			return paramsMap;
		// paramsMap.putAll(getAttributesMap(request));
		Map<String, String[]> params = request.getParameterMap();
		for (String key : params.keySet()) {
			paramsMap.put(key, params.get(key)[0]);
		}
		return paramsMap;
	}

	/**
	 * 从request中取出值,注入到方法参数中
	 * 
	 * @param kvMap
	 * @param clazz
	 * @param method
	 * @return
	 */
	public static Object[] paramsObject(Map<String, Object> kvMap, Class<?> clazz, Method method) {
		if (kvMap.isEmpty())
			return null;
		String[] names = null;
		Class<?>[] paramTypes = method.getParameterTypes();
		try {
			if (paramTypes == null) { // 执行无参数的方法
				names = MethodTool.getMethodParamNames(clazz, method.getName());
			} else { // 执行有具体参数的方法
				names = MethodTool.getMethodParamNames(clazz, method.getName(), paramTypes);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (names == null)
			return null;
		Object[] args = new Object[names.length];
		for (int i = 0; i < names.length; i++) {
			args[i] = kvMap.get(names[i]);
		}
		return args;
	}

}
